package com.iteaj.iot.test.modbus;

import com.iteaj.iot.client.ClientProtocolHandle;
import com.iteaj.iot.modbus.ModbusTcpHeader;
import com.iteaj.iot.modbus.Payload;
import com.iteaj.iot.modbus.client.ModbusTcpClientCommonProtocol;
import com.iteaj.iot.modbus.client.ModbusTcpClientComponent;
import com.iteaj.iot.modbus.consts.ModbusBitStatus;
import com.iteaj.iot.modbus.consts.ModbusCoilStatus;
import com.iteaj.iot.test.TestConst;
import com.iteaj.iot.utils.ByteUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;

import java.time.Instant;

public class ModbusTestHandle implements ClientProtocolHandle<ModbusTcpClientCommonProtocol>, InitializingBean {

    @Autowired
    private ThreadPoolTaskScheduler scheduler;
    @Autowired
    private ModbusTcpClientComponent modbusTcpClientComponent;

    private Logger logger = LoggerFactory.getLogger(getClass());

    @Override
    public Object handle(ModbusTcpClientCommonProtocol protocol) {
        return null;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        scheduler.schedule(() -> {
            System.out.println("------------------ modbus客户端测试时使用的服务端模拟工具地址(https://gitee.com/qsaker/QtSwissArmyKnife) -------------");

            //测试读写单个线圈
            ModbusCoilStatus write05 = ModbusCoilStatus.ON;
            ModbusTcpClientCommonProtocol.buildWrite05(1, 0, ModbusCoilStatus.ON).request();
            ModbusTcpClientCommonProtocol.buildRead01(1, 0, 1).request(protocol -> {
                ModbusTcpClientCommonProtocol commonProtocol = (ModbusTcpClientCommonProtocol) protocol;
                ModbusBitStatus modbusBitStatus = commonProtocol.getPayload().readStatus(0);

                boolean status = (write05 == ModbusCoilStatus.ON && modbusBitStatus == ModbusBitStatus.ON)
                        || (write05 == ModbusCoilStatus.OFF && modbusBitStatus == ModbusBitStatus.OFF);

                ModbusTcpHeader head = commonProtocol.requestMessage().getHead();
                logger.info(TestConst.LOGGER_MODBUS_DESC, modbusTcpClientComponent.getName()
                        , "Write05", head.getEquipCode(), head.getMessageId()
                        , status ? "通过" : "失败");
                return null;
            });

            // 测试读写多个线圈
            byte[] write0f = new byte[] {(byte) 0xFF};
            ModbusTcpClientCommonProtocol.buildWrite0F(1, 9, write0f).request();
            ModbusTcpClientCommonProtocol.buildRead01(1, 9, 13).request(protocol -> {
                ModbusTcpClientCommonProtocol commonProtocol = (ModbusTcpClientCommonProtocol) protocol;
                Payload payload = commonProtocol.getPayload();
                ModbusTcpHeader head = commonProtocol.requestMessage().getHead();
                logger.info(TestConst.LOGGER_MODBUS_DESC, modbusTcpClientComponent.getName()
                        , "Write0F", head.getEquipCode(), head.getMessageId()
                        , write0f[0] == payload.getPayload()[0] ? "通过" : "失败");
                return null;
            });

            // 写单个寄存器测试
            short write06 = 72;
            ModbusTcpClientCommonProtocol.buildWrite06(1, 3, ByteUtil.getBytesOfReverse(write06)).request();
            ModbusTcpClientCommonProtocol.buildRead03(1, 3, 1).request(protocol -> {
                ModbusTcpClientCommonProtocol commonProtocol = (ModbusTcpClientCommonProtocol) protocol;
                ModbusTcpHeader head = commonProtocol.requestMessage().getHead();
                short i = commonProtocol.getPayload().readShort(3);
                logger.info(TestConst.LOGGER_MODBUS_DESC, modbusTcpClientComponent.getName()
                        , "Write06", head.getEquipCode(), head.getMessageId()
                        , i == write06 ? "通过" : "失败");
                return null;
            });

            // 写多个寄存器测试
            int write10 = 1000000;
            ModbusTcpClientCommonProtocol.buildWrite10(1, 6, 2, ByteUtil.getBytesOfReverse(write10)).request();
            ModbusTcpClientCommonProtocol.buildRead03(1, 6, 2).request(protocol -> {
                ModbusTcpClientCommonProtocol commonProtocol = (ModbusTcpClientCommonProtocol) protocol;
                ModbusTcpHeader head = commonProtocol.requestMessage().getHead();
                int i = commonProtocol.getPayload().readInt(6);
                logger.info(TestConst.LOGGER_MODBUS_DESC, modbusTcpClientComponent.getName()
                        , "Write10", head.getEquipCode(), head.getMessageId()
                        , i == write10 ? "通过" : "失败");
                return null;
            });

        }, Instant.now().plusSeconds(8));
    }
}
